Перейти к основному содержимому

7.04. Справочник по GitHub Actions

Разработчику Архитектору Инженеру

Справочник по GitHub Actions

GitHub Actions — это система автоматизации рабочих процессов, встроенная непосредственно в платформу GitHub. Она позволяет выполнять последовательности задач (workflow) при наступлении определённых событий в репозитории: при пуше кода, создании pull request, по расписанию и других условиях. GitHub Actions предоставляет полный набор инструментов для сборки, тестирования, развертывания и мониторинга программного обеспечения без необходимости внешних CI/CD-сервисов.


Структура файла workflow

Файлы workflow описываются в формате YAML и размещаются в директории .github/workflows/ репозитория. Каждый файл представляет собой отдельный workflow с уникальным именем и набором заданий (jobs).

Пример минимальной структуры:

name: CI Build
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: echo "Hello, world!"

Корневые ключи workflow

name

Определяет имя workflow, отображаемое в интерфейсе GitHub. Имя может содержать любые символы, включая пробелы и эмодзи.

Пример:

name: Deploy to Production

Если ключ name не указан, GitHub использует имя файла как название workflow.


on

Определяет события, при которых запускается workflow. Поддерживает простую форму (массив строк) и расширенную (объект с параметрами).

Простая форма

on: push

или

on: [push, pull_request]

Расширенная форма

Позволяет указывать фильтры по веткам, тегам, путям и другим условиям.

Фильтрация по веткам и тегам
on:
push:
branches:
- main
- 'releases/**'
tags:
- v*
Фильтрация по путям
on:
push:
paths:
- 'src/**'
- '!src/test/**'
Запуск по расписанию (cron)
on:
schedule:
- cron: '0 2 * * 1' # Каждый понедельник в 2:00 UTC
Ручной запуск
on:
workflow_dispatch:
inputs:
logLevel:
description: 'Log level'
required: true
default: 'warning'
type: choice
options:
- info
- warning
- debug
Другие события
  • pull_request
  • pull_request_target
  • issue_comment
  • release
  • workflow_call — для вызова из другого workflow
  • repository_dispatch — для внешнего триггера через API

env

Задаёт глобальные переменные окружения для всего workflow. Эти переменные доступны во всех jobs и steps, если не переопределены локально.

env:
NODE_VERSION: '20'
CI: true

defaults

Устанавливает значения по умолчанию для шагов в рамках всего workflow.

defaults.run

Задаёт параметры по умолчанию для всех шагов с типом run.

defaults:
run:
shell: bash
working-directory: ./scripts

concurrency

Контролирует одновременное выполнение workflow. Позволяет отменять предыдущие запуски при новом срабатывании.

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

Группа определяет, какие запуски считаются конкурирующими. Переменная cancel-in-progress указывает, нужно ли прерывать уже запущенный workflow при старте нового.


jobs

Основной блок workflow. Содержит один или несколько job’ов — независимых задач, которые могут выполняться параллельно или последовательно.

Каждый job имеет уникальный идентификатор (ключ), который используется для ссылок между job’ами.


Определение job

name

Имя job’а, отображаемое в интерфейсе GitHub.

jobs:
test:
name: Run Unit Tests

runs-on

Указывает среду выполнения job’а. Поддерживает следующие значения:

  • ubuntu-latest, ubuntu-22.04, ubuntu-20.04
  • windows-latest, windows-2022, windows-2019
  • macos-latest, macos-13, macos-12
  • Собственные self-hosted runner’ы: self-hosted, linux, x64 и др.

Можно указать массив меток для выбора runner’а:

runs-on: [self-hosted, linux, x64]

environment

Связывает job с окружением, определённым в настройках репозитория. Это позволяет использовать защищённые секреты и применять правила защиты (например, ручное подтверждение перед деплоем).

environment: production

Также можно указать URL для отображения после успешного завершения:

environment:
name: production
url: https://example.com

permissions

Настраивает уровень доступа токена GITHUB_TOKEN внутри job’а. По умолчанию токен имеет ограниченные права (read-only для большинства ресурсов). Этот ключ позволяет явно разрешить или запретить действия.

Пример:

permissions:
contents: read
pull-requests: write
issues: read
deployments: write

Возможные области:

  • actions
  • checks
  • contents
  • deployments
  • discussions
  • id-token
  • issues
  • packages
  • pages
  • pull-requests
  • repository-projects
  • security-events
  • statuses

Значения: read, write, none.


if

Условие выполнения job’а. Если выражение возвращает false, job пропускается.

if: github.event_name == 'push'

Поддерживает все функции и контексты GitHub Actions.


needs

Задаёт зависимости между job’ами. Job будет запущен только после успешного завершения указанных job’ов.

jobs:
build:
...
test:
needs: build
...
deploy:
needs: [build, test]
...

outputs

Позволяет job’у экспортировать данные, доступные другим job’ам через needs.

jobs:
build:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.set_version.outputs.version }}
steps:
- id: set_version
run: echo "version=1.2.3" >> $GITHUB_OUTPUT
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- run: echo "Deploying version ${{ needs.build.outputs.version }}"

strategy

Позволяет запускать job с разными конфигурациями (матрица).

matrix

Определяет набор переменных и их значений для генерации комбинаций.

strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node: ['18', '20']

Это создаст 4 job’а: (ubuntu, 18), (ubuntu, 20), (windows, 18), (windows, 20).

Можно исключить комбинации:

strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node: ['18', '20']
exclude:
- os: windows-latest
node: '18'

Можно добавить дополнительные конфигурации:

include:
- os: macos-latest
node: '20'
experimental: true

fail-fast

Если true (по умолчанию), при падении одного из job’ов матрицы остальные отменяются.

strategy:
fail-fast: false
matrix:
python: ['3.8', '3.9', '3.10']

max-parallel

Ограничивает количество одновременно выполняемых job’ов в матрице.

strategy:
max-parallel: 2
matrix:
version: [1, 2, 3, 4, 5]

steps

Список последовательных действий внутри job’а. Каждый шаг — это либо выполнение команды (run), либо использование действия (uses).

Общие поля шага

  • id — уникальный идентификатор шага для ссылок (${{ steps.id.outputs.key }})
  • name — описание шага
  • if — условие выполнения
  • env — переменные окружения, специфичные для шага
  • working-directory — рабочая директория для шага
  • continue-on-error — если true, шаг не прервёт job при ошибке
  • timeout-minutes — максимальное время выполнения шага

Тип шага: run

Выполняет команду в оболочке операционной системы.

- name: Install dependencies
run: npm install

Можно указать оболочку явно:

- run: |
echo "Multi-line"
echo "script"
shell: bash

Поддерживаемые оболочки:

  • Linux/macOS: bash, sh, pwsh, python, perl, ruby
  • Windows: cmd, pwsh, powershell

Тип шага: uses

Использует готовое действие (action). Action может быть:

  • Официальным (actions/checkout@v4)
  • Из другого репозитория (user/repo@v1)
  • Локальным (./.github/actions/my-action)
  • Docker-образом (docker://alpine:latest)

Пример:

- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'

Параметры действия: with

Передаёт входные параметры в action.

- uses: actions/upload-artifact@v4
with:
name: logs
path: ./logs/

Каждое действие документирует свои входные параметры в action.yml.


Вывод действия: outputs

Действия могут возвращать данные через outputs. Они доступны через ${{ steps.id.outputs.key }}.

Пример:

- id: get-time
uses: some/action-that-outputs-time@v1
- run: echo "Time was ${{ steps.get-time.outputs.timestamp }}"

Контексты и встроенные функции

GitHub Actions предоставляет набор контекстов — структурированных объектов, содержащих информацию о workflow, job’е, runner’е, событии и других аспектах выполнения. Контексты доступны через синтаксис ${{ }}.

Основные контексты

github

Содержит данные о текущем запуске workflow.

Часто используемые поля:

  • github.ref — ссылка на ветку или тег (например, refs/heads/main)
  • github.ref_name — имя ветки или тега (main, v1.0.0)
  • github.sha — хеш коммита
  • github.event_name — имя события (push, pull_request, schedule)
  • github.repository — имя репозитория (owner/repo)
  • github.repository_owner — владелец репозитория
  • github.run_id — уникальный ID запуска workflow
  • github.workflow — имя текущего workflow
  • github.actor — имя пользователя, инициировавшего событие
  • github.server_url — URL сервера (https://github.com)
  • github.workspace — путь к рабочей директории на runner’е

Пример:

- run: echo "Running on branch ${{ github.ref_name }}"

env

Содержит переменные окружения, заданные через env на уровне workflow, job или step.

- run: echo "Node version is ${{ env.NODE_VERSION }}"

job

Содержит информацию о текущем job’е (редко используется напрямую).

steps

Содержит выходные данные (outputs) предыдущих шагов.

- id: build
run: echo "image=app:v1" >> $GITHUB_OUTPUT
- run: echo "Deploying ${{ steps.build.outputs.image }}"

runner

Содержит информацию о среде выполнения.

Поля:

  • runner.os — операционная система (Linux, Windows, macOS)
  • runner.arch — архитектура (X86, ARM64)
  • runner.temp — временная директория

secrets

Содержит защищённые переменные, заданные в настройках репозитория или организации.

- run: ./deploy.sh --token ${{ secrets.DEPLOY_TOKEN }}

Важно: значения из secrets никогда не отображаются в логах, даже при ошибке.

inputs

Доступен только в workflow, вызванном через workflow_call. Содержит входные параметры.

on:
workflow_call:
inputs:
environment:
type: string
required: true
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- run: echo "Deploying to ${{ inputs.environment }}"

Встроенные функции

Функции используются внутри выражений ${{ }} для обработки строк, массивов, условий и др.

contains

Проверяет наличие подстроки или элемента в массиве.

if: contains(github.ref, 'refs/tags/')

startsWith, endsWith

Проверяют начало или конец строки.

if: startsWith(github.ref, 'refs/heads/release')

format

Форматирует строку по шаблону.

- run: echo "${{ format('Hello, {0}!', github.actor) }}"

join

Объединяет элементы массива в строку.

- run: echo "${{ join(matrix.os, ', ') }}"

fromJSON, toJSON

Преобразуют JSON-строку в объект и обратно.

env:
CONFIG: '{"debug":true}'
- run: echo "${{ fromJSON(env.CONFIG).debug }}"

hashFiles

Вычисляет хеш содержимого файлов (часто используется для кэширования).

- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ hashFiles('**/package-lock.json') }}

always(), success(), failure(), cancelled()

Управляют выполнением шагов независимо от статуса предыдущих.

- if: failure()
run: echo "Job failed"

needs.*.result

Позволяет проверить результат завершённого job’а.

if: needs.test.result == 'success'

Секреты и безопасность

Типы секретов

  • Репозиторий: задаются в Settings → Secrets and variables → Actions.
  • Организация: задаются на уровне организации, могут быть унаследованы репозиториями.
  • Environment secrets: привязаны к конкретному окружению (например, production).

Рекомендации по безопасности

  • Никогда не выводите секреты в логи.
  • Используйте минимально необходимые права для GITHUB_TOKEN.
  • Для деплоя в сторонние системы используйте отдельные токены с ограниченными правами.
  • Не храните секреты в коде или файлах конфигурации.

Артефакты

Артефакты — это файлы, сохраняемые между job’ами или для последующего скачивания.

Сохранение артефакта

- uses: actions/upload-artifact@v4
with:
name: coverage-report
path: ./coverage/

Загрузка артефакта

- uses: actions/download-artifact@v4
with:
name: coverage-report
path: ./reports/

Артефакты хранятся до 90 дней (или меньше, если задано в настройках).


Вызов workflow из другого workflow

Можно вызывать один workflow из другого с помощью workflow_call.

Вызываемый workflow (called-workflow.yml):

on:
workflow_call:
inputs:
version:
type: string
required: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo "Building version ${{ inputs.version }}"

Вызывающий workflow:

jobs:
call-build:
uses: ./.github/workflows/called-workflow.yml
with:
version: '2.1.0'

Это позволяет создавать переиспользуемые компоненты автоматизации.


Best practices

Использование официальных действий

Предпочтительно использовать действия из actions/* (например, checkout, setup-node, upload-artifact), так как они поддерживаются GitHub и регулярно обновляются.

Версионирование действий

Всегда указывайте конкретную версию действия:

uses: actions/checkout@v4  # ✅
uses: actions/checkout@main # ❌

Кэширование зависимостей

Ускоряет сборку за счёт повторного использования установленных пакетов.

- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

Избегание hard-coded путей

Используйте ${{ github.workspace }} вместо абсолютных путей.

Минимизация прав

Явно ограничивайте permissions до необходимого минимума.

Использование concurrency

Предотвращает накопление устаревших запусков при частых пулах.


Примеры сложных workflow

Мультиплатформенная сборка и тестирование

Этот workflow собирает и тестирует проект на трёх операционных системах с разными версиями Node.js.

name: Cross-Platform Tests

on:
push:
branches: [main]
pull_request:

jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: ['18', '20', '22']
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm test

Деплой с ручным подтверждением (environment approval)

Workflow ожидает одобрения от ответственного лица перед деплоем в production.

name: Deploy to Production

on:
workflow_dispatch:

jobs:
deploy:
environment: production
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./deploy.sh
- name: Notify success
run: echo "Deployment completed"

В настройках окружения production в GitHub необходимо включить Required reviewers и назначить одного или нескольких пользователей.


Генерация и публикация sitemap

Workflow запускается еженедельно, генерирует карту сайта и коммитит её в репозиторий.

name: Weekly Sitemap Update

on:
schedule:
- cron: '0 3 * * 1' # Понедельник, 3:00 UTC

jobs:
update-sitemap:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- run: npm install
- run: npm run generate-sitemap
- name: Commit sitemap
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
git add sitemap.xml
git diff --staged --quiet || git commit -m "chore: update sitemap"
git push

Сборка Docker-образа и публикация в GitHub Packages

name: Build and Publish Docker Image

on:
push:
tags: ['v*']

jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.ref_name }}

Использование self-hosted runner’а

Для выполнения задач на собственном сервере указывается метка self-hosted.

jobs:
deploy-internal:
runs-on: [self-hosted, linux, production]
steps:
- uses: actions/checkout@v4
- run: ./internal-deploy.sh

Self-hosted runner должен быть предварительно зарегистрирован в репозитории или организации и запущен как служба.


Работа с артефактами между job’ами

Передача данных через артефакты полезна, когда job’ы выполняются на разных runner’ах.

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- run: rsync -av dist/ user@server:/var/www/

Условное выполнение шагов

Использование if для контроля потока выполнения.

- name: Notify on failure
if: failure()
run: curl -X POST -d "Build failed" ${{ secrets.SLACK_WEBHOOK }}

- name: Run only on main
if: github.ref == 'refs/heads/main'
run: echo "Main branch"

- name: Skip on forks
if: github.event.pull_request.head.repo.full_name == github.repository
run: echo "Not a fork"

Работа с секретами и переменными

Секреты задаются в Settings → Secrets and variables → Actions.
Переменные окружения — в том же разделе, но во вкладке Variables.

Пример использования:

env:
API_URL: ${{ vars.API_URL }}

steps:
- run: ./test.sh --api $API_URL --token ${{ secrets.API_TOKEN }}

Отладка workflow

  • Включить подробный лог: добавить секрет ACTIONS_STEP_DEBUG со значением true.
  • Использовать echo для вывода значений.
  • Проверять тип runner’а и переменные через printenv.

Ограничения GitHub Actions

  • Время выполнения job’а: до 6 часов.
  • Общий объём артефактов: до 10 ГБ на репозиторий.
  • Частота запусков по расписанию: не чаще одного раза в 5 минут.
  • Количество параллельных job’ов зависит от типа аккаунта (Free, Pro, Enterprise).